param( $SourceManifestFile, $DestinationManifestFile, $SourceManifest, $DestinationManifest )

function ReadManifestDoc([xml]$doc)
{
	$manifiestFiles = @{}
	if ($doc.Files.File -ne $null)
	{
		foreach ($file in $doc.Files.File)
		{
			$fileItem = New-Object PSObject
			Add-Member -InputObject $fileItem -MemberType Note* -Name RelativePath -Value $file.RelativePath
			Add-Member -InputObject $fileItem -MemberType Note* -Name Length -Value $file.Length
			Add-Member -InputObject $fileItem -MemberType Note* -Name Checksum -Value $file.Checksum
			$manifiestFiles[$file.RelativePath] = $fileItem
		}
	}
	$manifiestFiles
}
function ReadManifestFile($manifestFile)
{
	[xml]$doc = get-content $manifestFile
	ReadManifestDoc $doc
}

if($SourceManifestFile -eq $null)
{
	if($SourceManifest -eq $null)
	{
		throw "SourceManifestFile or SourceManifest are required"
	}
	$src = ReadManifestDoc $SourceManifest
}
else
{
	$src = ReadManifestFile $SourceManifestFile
}

if($DestinationManifestFile -eq $null)
{
	if($DestinationManifest -eq $null)
	{
		throw "DestinationManifestFile or DestinationManifest are required"
	}
	$des = ReadManifestDoc $DestinationManifest
}
else
{
	$des = ReadManifestFile $DestinationManifestFile
}

$ChangedFiles = New-Object System.Collections.ArrayList
$DeletedFiles = New-Object System.Collections.ArrayList
$AddedFiles = New-Object System.Collections.ArrayList
$RenamedFiles = New-Object System.Collections.ArrayList

foreach ($key in $src.keys)
{
	if ($des[$key] -eq $null)
	{
		[void]$AddedFiles.Add($src[$key])
	}
	else
	{
		if ($src[$key].Checksum -ne $des[$key].Checksum)
		{
  		[void]$ChangedFiles.Add($src[$key])
		}
		$des.Remove($key)
	}
}

foreach ($deskey in $des.keys)
{
  [void]$DeletedFiles.Add($des[$deskey])
}

foreach ($AddedFile in ( $AddedFiles | %{$_}))
{
	foreach ($DeletedFile in ($DeletedFiles | %{$_}))
	{
		if ($DeletedFile.Checksum -eq $AddedFile.Checksum)
		{
		  [void]$DeletedFiles.Remove($DeletedFile)
		  [void]$AddedFiles.Remove($AddedFile)
			[void]$RenamedFiles.Add(@{Old=$DeletedFile;New=$AddedFile})
		}
	}
}

@{Added=$AddedFiles;Deleted=$DeletedFiles;Changed=$ChangedFiles;Renamed=$RenamedFiles}
